Básico do Doctrine 2 no ZF2
Veja o básico do Doctrine 2 no ZF2
Esse post é continuação do Post de instalação do Doctrine 2 no ZF2. Agora faremos um CRUD simples.
Preparação
Antes de iniciar, apenas crie uma tabela nova com o seguinte código:
CREATE TABLE `content` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`content` varchar(100) NOT NULL
) COMMENT='';
Depois disso, prepare um Entity de conteúdo para a tabela acima. Copie o código abaixo em ~/module/Application/src/Application/Entity/Content.php
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Content
*
* @ORM\Table(name="content")
* @ORM\Entity
*/
class Content {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="content", type="string", length=127, nullable=false)
*/
private $content;
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
return $this;
}
public function getContent() {
return $this->content;
}
public function setContent($content) {
$this->content = $content;
return $this;
}
}
Esse código é o seu Modelo da entidade que criamos. Veja que ele é bem simples, e já possui informações suficientes para trocar informações com o banco de dados, que no caso é de uma tabela com apenas dois campos (id e content).
Nos próximos passos, vamos fazer o CRUD aos poucos. Será tudo em uma só página, apenas para fins didáticos.
Adicionar
Create, do CRUD, vamos inserir conteúdos na nossa tabela. Vamos começar com a página de inserção (~/module/Application/view/application/index/index.phtml):
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" method="POST">
<input type="hidden" name="action" value="insert" />
<fieldset>
<!-- Form Name -->
<legend>Adicionar conteúdo</legend>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-12 control-label" for="content">Text Area</label>
<div class="col-md-12">
<textarea class="form-control" id="content" name="content"></textarea>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-12 control-label" for="insert"></label>
<div class="col-md-12">
<button id="insert" name="insert" class="btn btn-primary">Novo</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
De importante, temos um formulário, nossa action de inserir (para diferenciar quando formos atualizar), a informação de conteúdo e o botão. Você já deve visualizar a seguinte página:
Porém, isso ainda não funciona. Vamos preparar nosso controller. Altere o indexAction do controller já existente (~/module/Application/src/Application/Controller/IndexController.php) para o seguinte:
class IndexController extends AbstractActionController
{
public function indexAction()
{
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
// Add
if ($data['action'] == 'insert') {
// New
$entity = new Content();
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
}
return new ViewModel();
}
protected function getEm() {
if (null === $this->em)
$this->em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
return $this->em;
}
}
A função getEm() busca o serviço do Doctrine2. Você vai utilizar muito, então já deixo pronta com a protected function. E para adicionar, basta criar um novo objeto, e inserí-lo com o Doctrine (primeiro persiste na base de dados, e depois executa com o flush).
E pronto. Já funciona o insert (verifique no Banco de Dados se inseriu, ou avance para o próximo passo).
Visualizar
Para visualizar, vamos buscar todos os resultados do BD. Vamos fazer 2 coisinhas.
Faça com que o controller retorne todos os conteúdos (edite o IndexAction):
public function indexAction()
{
$vars = array();
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
// Add
if ($data['action'] == 'insert') {
// New
$entity = new Content();
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
}
// List
$contents = $this->getEm()->getRepository('Application\Entity\Content')->findAll();
$vars['contents'] = $contents;
return new ViewModel($vars);
}
E faça com que apareça nas views com o seguinte:
<!-- Abaixo do formulário de adicionar -->
<div class="row">
<?php foreach ($contents as $content) : ?>
<div class="col-md-12">
<p><?php echo $content->getContent(); ?></p>
</div>
<?php endforeach; ?>
</div>
E se tudo funcionou, logo abaixo do formulário você visualiza o que já inseriu no BD:
Editar
Agora vamos editar os dados. Vou criar um formulário para cada um dos resultados. Assim, vou editar a view. Apague o que antes era:
<!-- Abaixo do formulário de adicionar -->
<div class="row">
<?php foreach ($contents as $content) : ?>
<div class="col-md-12">
<p><?php echo $content->getContent(); ?></p>
</div>
<?php endforeach; ?>
</div>
Agora isso irá virar:
<div class="row">
<?php foreach ($contents as $content) : ?>
<hr />
<div class="col-md-12">
<form class="form-horizontal" method="POST">
<input type="hidden" name="action" value="update" />
<input type="hidden" name="id" value="<?php echo $content->getId(); ?>" />
<fieldset>
<!-- Form Name -->
<legend>Editar conteúdo <?php echo $content->getId(); ?></legend>
<p><?php echo $content->getContent(); ?></p>
<!-- Textarea -->
<div class="form-group">
<div class="col-md-12">
<textarea class="form-control" id="content" name="content"><?php echo $content->getContent(); ?></textarea>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-12 control-label" for="insert"></label>
<div class="col-md-12">
<button id="insert" name="insert" class="btn btn-primary">Editar</button>
</div>
</div>
</fieldset>
</form>
</div>
<?php endforeach; ?>
</div>
O formulário tem 2 diferenças principais. O action, que agora é update, e um campo do id que desejamos editar.
Por fim, vamos editar nosso controller, adicionando a opção de update:
public function indexAction()
{
$vars = array();
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
// Add
if ($data['action'] == 'insert') {
// New
$entity = new Content();
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
// Update
if ($data['action'] == 'update') {
$entity = $this->getEm()->getRepository('Application\Entity\Content')->find($data['id']);
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
}
// List
$contents = $this->getEm()->getRepository('Application\Entity\Content')->findAll();
$vars['contents'] = $contents;
return new ViewModel($vars);
}
E com isso, você já pode editar seus dados.
Deletar
E agora, vamos terminar o CRUD com a deleção. Vamos criar um botão para isso na view.
<div class="row">
<?php foreach ($contents as $content) : ?>
<hr />
<div class="col-md-12">
<form class="form-horizontal" method="POST">
<input type="hidden" name="action" value="update" />
<input type="hidden" name="id" value="<?php echo $content->getId(); ?>" />
<fieldset>
<!-- Form Name -->
<legend>Editar conteúdo <?php echo $content->getId(); ?></legend>
<p><?php echo $content->getContent(); ?></p>
<!-- Textarea -->
<div class="form-group">
<div class="col-md-12">
<textarea class="form-control" id="content" name="content"><?php echo $content->getContent(); ?></textarea>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-12 control-label" for="insert"></label>
<div class="col-md-12">
<button id="insert" name="insert" class="btn btn-primary">Editar</button>
</div>
</div>
</fieldset>
</form>
<form class="form-horizontal" method="POST">
<input type="hidden" name="action" value="delete" />
<input type="hidden" name="id" value="<?php echo $content->getId(); ?>" />
<button class="btn btn-danger">Apagar</button>
</form>
</div>
<?php endforeach; ?>
</div>
A única coisa que adicionei foi esse formulário para apagar (ok, sei que não precisava ter criado 2 forms, mas separado assim fica fácil de entender).
E para isso funcionar, terminemos nosso Controller:
public function indexAction()
{
$vars = array();
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
// Add
if ($data['action'] == 'insert') {
// New
$entity = new Content();
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
// Update
if ($data['action'] == 'update') {
$entity = $this->getEm()->getRepository('Application\Entity\Content')->find($data['id']);
$entity->setContent($data['content']);
// Persist
$this->getEm()->persist($entity);
$this->getEm()->flush();
}
// Delete
if ($data['action'] == 'delete') {
$entity = $this->getEm()->getReference('Application\Entity\Content', $data['id']);
// Remove
$this->getEm()->remove($entity);
$this->getEm()->flush();
}
}
// List
$contents = $this->getEm()->getRepository('Application\Entity\Content')->findAll();
$vars['contents'] = $contents;
return new ViewModel($vars);
}
E incluímos como remover. Percebeu que agora usamos o getReference, ao invés do find? Isso é mais prático, para não precisar fazer uma busca no BD antes de deletar (isso poderia ser feito com o update também).
Fim
Apenas tarefas básicas, mas poderosas. Espero que tenham gostado, e qualquer problema deixem nos comentários :)